#include "Int_SP3485.h"
#include "stddef.h"
#include "string.h"

// 定义 GPIO 引脚用于控制 DE/RE#
#define RS485_DE_RE_PIN GPIO_Pin_1
#define RS485_DE_RE_PORT GPIOA

#define RS485_TX_PIN GPIO_Pin_2
#define RS485_RX_PIN GPIO_Pin_3

// 全局变量：存储接收到的数据
#define RX_BUFFER_SIZE 64

uint8_t g_rx_buffer[RX_BUFFER_SIZE]; // 接收缓冲区
uint16_t g_rx_index = 0;             // 当前索引
uint8_t g_string_ready = 0;          // 字符串就绪标志

void Int_SP3485_Init(void)
{
    // 开启时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); // 开启USART2的时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  // 开启GPIOA的时钟

    // GPIO初始化
    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin = RS485_TX_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure); // 将PA9引脚初始化为复用推挽输出

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Pin = RS485_RX_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure); // 将PA10引脚初始化为上拉输入

    GPIO_InitStructure.GPIO_Pin = RS485_DE_RE_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 默认设置为接收模式
    GPIO_ResetBits(GPIOA, RS485_DE_RE_PIN);

    // USART初始化
    USART_InitTypeDef USART_InitStructure;

    USART_InitStructure.USART_BaudRate = 9600;                                      // 波特率
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 硬件流控制，不需要
    USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;                 // 模式，发送模式和接收模式均选择
    USART_InitStructure.USART_Parity = USART_Parity_No;                             // 奇偶校验，不需要
    USART_InitStructure.USART_StopBits = USART_StopBits_1;                          // 停止位，选择1位
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;                     // 字长，选择8位
    USART_Init(USART2, &USART_InitStructure);                                       // 将结构体变量交给USART_Init，配置USART2

    /*中断输出配置*/
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); // 开启串口接收数据的中断
    // 空闲帧配置
    USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);

    /*NVIC中断分组*/
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 配置NVIC为分组2

    // NVIC配置
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_Init(&NVIC_InitStructure);

    USART_Cmd(USART2, ENABLE);
}

void Int_SP3485_SendByte(uint8_t byte)
{
    // 切换为发送模式
    GPIO_SetBits(GPIOA, RS485_DE_RE_PIN);

    // 等待发送缓冲区空
    while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
        ;

    // 发送数据
    USART_SendData(USART2, byte);

    // 等待发送完成
    while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)
        ;

    // 恢复接收模式
    GPIO_ResetBits(GPIOA, RS485_DE_RE_PIN);
}

void Int_SP3485_SendData(uint8_t *data, uint16_t length)
{
    if (data == NULL || length == 0)
    {
        return;
    }
    // 切换为发送模式
    GPIO_SetBits(GPIOA, RS485_DE_RE_PIN);

    for (uint16_t i = 0; i < length; i++)
    {
        while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)
            ;
        USART_SendData(USART2, data[i]);
    }

    while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)
        ;

    GPIO_ResetBits(GPIOA, RS485_DE_RE_PIN);
}

void Int_SP3485_SendString(char *string)
{
    if (string == NULL)
    {
        return;
    }
    Int_SP3485_SendData((uint8_t *)string, strlen(string));
}

uint8_t Int_SP3485_GetReceivedString(uint8_t *buffer, uint16_t *length)
{
    if (g_string_ready)
    {
        strcpy((char*)buffer, (char*)g_rx_buffer);
        *length = strlen((char*)g_rx_buffer);
        g_string_ready = 0;
        return 1;
    }
    return 0;
}

// USART2 中断服务函数
void USART2_IRQHandler(void)
{
    if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
    {
        // 正常接收字节
        uint8_t data = USART_ReceiveData(USART2);
        if (g_rx_index < RX_BUFFER_SIZE - 1)
        {
            g_rx_buffer[g_rx_index++] = data;
        }
        else
        {
            g_rx_index = 0;
        }
    }

    if (USART_GetITStatus(USART2, USART_IT_IDLE) != RESET)
    {
        // 清除空闲中断标志
        USART_ClearFlag(USART2, USART_FLAG_IDLE);
        g_rx_buffer[g_rx_index] = '\0';
        g_string_ready = 1;
        g_rx_index = 0;
    }
}
